import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';


export interface DataContainer<E> {
  api: string;
  filter?: SearchFilter;
  pagination: Pagination;
  data?: E;
  totalCount?: number;
  orders?: OrderField[];
  status: boolean;
}

export interface SearchFilter {
  [name: string]: SearchFilterItem;
}

export interface SearchFilterItem {
  eq?: string | number | boolean | null;
  neq?: string | number | boolean | null;
  lt?: string | number;
  lte?: string | number;
  gt?: string | number;
  gte?: string | number;
  in?: Array<string | number>;
  nin?: Array<string | number>;
  like?: string;
}

export interface Pagination {
  first: number;
  offset: number;
}

export interface OrderField {
  name: string;
  type: 'ASC' | 'DESC';
}

export interface RestfulService<E> {

  searchObs(): Observable<DataContainer<E[]>>;

  index(params: any, success: (res: any) => void): void;

  search(): void;

  setFilter(filter: SearchFilter): void;

  setFirst(first: number): void;

  setOffset(offset: number): void;

  setOrderFields(orders: OrderField[]): void;

  save(e: E, success: (res: any) => void, error: () => void): void;

  remove(e: E, success: (res: any) => void, error: () => void): void;

  removes(list: [E], success: (res: any) => void, error: () => void): void;
}

@Injectable({
  providedIn: 'root'
})
export class SearcherTools<VO>{

  constructor(private http: HttpClient) { }

  async search(data: DataContainer<VO>): Promise<DataContainer<VO>> {
    return this.http.post(data.api, data.filter, { withCredentials: true }).pipe(map(res => res as any), map(res => {
      data.data = res.rows;
      data.totalCount = res.total;
      data.status = true;
      return data;
    })).toPromise();

  }
}
